#[derive(Debug, PartialEq)]
struct Arc {
    radius: f64,
    theta: f64, // 弧度 中心角
}

// 通过半径和弧度创建一个弧
pub fn from_arc_length_and_radius(arc_length: f64, radius: f64) -> Arc {
    // 初始猜测中心角的值
    let mut theta_guess = arc_length / radius;

    // 牛顿迭代法求解方程 s = r * theta
    let epsilon = 1e-10; // 精度要求
    let mut theta_prev;

    loop {
        theta_prev = theta_guess;
        let f_theta = radius * theta_prev - arc_length;
        let f_prime_theta = radius; // 导数 f'(θ) = r
        theta_guess = theta_prev - f_theta / f_prime_theta;

        if (theta_guess - theta_prev).abs() < epsilon {
            break;
        }
    }

    Arc {
        radius,
        theta: theta_guess,
    }
}

//已知圆弧的两个断点坐标求圆弧
/// 已知圆弧的两个端点坐标求圆弧
pub fn from_endpoints(x1: f64, y1: f64, x2: f64, y2: f64) -> Arc {
    // 计算半径
    let radius = ((x2 - x1).powi(2) + (y2 - y1).powi(2)).sqrt();

    // 计算圆心坐标
    let center_x = (x1 + x2) / 2.0;
    let center_y = (y1 + y2) / 2.0;

    // 计算中心角
    let v1_x = x1 - center_x;
    let v1_y = y1 - center_y;
    let v2_x = x2 - center_x;
    let v2_y = y2 - center_y;

    let dot_product = v1_x * v2_x + v1_y * v2_y;
    let magnitude_product = (v1_x.powi(2) + v1_y.powi(2)).sqrt() * (v2_x.powi(2) + v2_y.powi(2)).sqrt();

    let cos_theta = dot_product / magnitude_product;
    let theta = cos_theta.acos();

    Arc { radius, theta }
}


/// 已知圆弧的面积和半径求圆弧
pub fn from_area_and_radius(area: f64, radius: f64) -> Arc {
    // 计算弧长
    let arc_length = (area * 2.0 / radius).sqrt();

    // 计算中心角
    let theta = arc_length / radius;

    Arc { radius, theta }
}

/// 生成圆弧上的点
pub fn generate_points(&self, num_points: usize) -> Vec<Point> {
    let mut points = Vec::with_capacity(num_points);

    for i in 0..num_points {
        let theta_increment = self.theta / (num_points as f64 - 1.0);
        let current_theta = i as f64 * theta_increment;
        let x = self.radius * current_theta.cos();
        let y = self.radius * current_theta.sin();
        points.push(Point { x, y });
    }

    points
}


//切线方程
#[derive(Debug)]
pub struct Tangent {
    pub A: f64,
    pub B: f64,
    pub C: f64,
}

#[derive(Debug, PartialEq)]
struct Arc {
    radius: f64,
    theta: f64, // 中心角，以弧度表示
}

impl Arc {
    // 计算圆弧上一点的坐标
    pub fn point_on_arc(&self, angle: f64) -> (f64, f64) {
        let x = self.radius * angle.cos();
        let y = self.radius * angle.sin();
        (x, y)
    }

    // 计算圆弧上的切线方程
    fn tangent_at_point(&self, angle: f64) -> Tangent {
        // 计算两个相邻点的坐标
        let (x1, y1) = self.point_on_arc(angle);
        let epsilon = 1e-8;
        let (x2, y2) = self.point_on_arc(angle + epsilon);

        // 计算切线方程的一般式表示
        let a = y2 - y1;
        let b = x1 - x2;
        let c = x2 * y1 - x1 * y2;

        Tangent { A: a, B: b, C: c }
    }
}

// 计算法线方程
pub fn normal_at_point(&self, angle: f64) -> LinearEquation {
    // 计算切线方程的斜率
    let tangent_slope = -(self.radius * self.theta.sin()) / (self.radius * self.theta.cos());

    // 计算法线斜率
    let normal_slope = -1.0 / tangent_slope;

    // 计算法线方程的常数
    let (x0, y0) = self.point_on_arc(angle);
    let normal_constant = y0 - normal_slope * x0;

    LinearEquation {
        A: normal_slope,
        B: -1.0,
        C: normal_constant,
    }
}

//旋转三角形
// 绕着指定点旋转三角形，返回新的三角形实例
pub fn rotate_around_point(&self, center: &Point, angle_degrees: f64) -> Triangle {
    // 将角度转换为弧度
    let angle_radians = angle_degrees.to_radians();

    // 定义旋转矩阵
    let rotation_matrix = [
        [angle_radians.cos(), -angle_radians.sin()],
        [angle_radians.sin(), angle_radians.cos()],
    ];

    // 对每个顶点进行旋转
    let new_vertex_a = self.rotate_point(&self.vertex_a, center, rotation_matrix);
    let new_vertex_b = self.rotate_point(&self.vertex_b, center, rotation_matrix);
    let new_vertex_c = self.rotate_point(&self.vertex_c, center, rotation_matrix);

    Triangle {
        vertex_a: new_vertex_a,
        vertex_b: new_vertex_b,
        vertex_c: new_vertex_c,
    }
}
/// 旋转单个点
fn rotate_point(&self, point: &Point, center: &Point, matrix: [[f64; 2]; 2]) -> Point {
    let translated_x = point.x - center.x;
    let translated_y = point.y - center.y;

    let rotated_x = matrix[0][0] * translated_x + matrix[0][1] * translated_y;
    let rotated_y = matrix[1][0] * translated_x + matrix[1][1] * translated_y;

    Point {
        x: rotated_x + center.x,
        y: rotated_y + center.y,
    }
}



// 判断点是否在三角形内
pub fn point_inside_triangle(&self, p: &Point) -> bool {
    // 计算重心坐标
    let barycentric_coords = self.barycentric_coordinates(p);

    // 判断点是否在三角形内
    barycentric_coords.iter().all(|&coord| coord >= 0.0 && coord <= 1.0)
}

// 辅助方法，计算点的重心坐标
pub fn barycentric_coordinates(&self, p: &Point) -> [f64; 3] {
    // 计算三个子三角形的面积
    let area_triangle = self.area();
    let area_sub_triangle_a = Triangle::new(p.clone(), self.vertex_b.clone(), self.vertex_c.clone()).area();
    let area_sub_triangle_b = Triangle::new(self.vertex_a.clone(), p.clone(), self.vertex_c.clone()).area();
    let area_sub_triangle_c = Triangle::new(self.vertex_a.clone(), self.vertex_b.clone(), p.clone()).area();

    // 计算重心坐标
    let p1 = area_sub_triangle_a / area_triangle;
    let p2 = area_sub_triangle_b / area_triangle;
    let p3 = area_sub_triangle_c / area_triangle;

    [p1, p2, p3]
}

// 计算垂心
pub fn orthocenter(&self) -> Point {
    let x_h = self.vertex_a.x;
    let y_h = self.vertex_b.y;
    Point { x: x_h, y: y_h }
}

// 计算重心
pub fn centroid(&self) -> Point {
    let x_g = (self.vertex_a.x + self.vertex_b.x + self.vertex_c.x) / 3.0;
    let y_g = (self.vertex_a.y + self.vertex_b.y + self.vertex_c.y) / 3.0;
    Point { x: x_g, y: y_g }
}

// 计算内心
pub fn incenter(&self) -> Point {
    let a = self.vertex_b.distance_to(&self.vertex_c);
    let b = self.vertex_c.distance_to(&self.vertex_a);
    let c = self.vertex_a.distance_to(&self.vertex_b);


    let x_i = (a * self.vertex_a.x + b * self.vertex_b.x + c * self.vertex_c.x) / (a + b + c);
    let y_i = (a * self.vertex_a.y + b * self.vertex_b.y + c * self.vertex_c.y) / (a + b + c);

    Point { x: x_i, y: y_i }
}

// 计算外心
pub fn circumcenter(&self) -> Point {
    let m_ab = Point {
        x: (self.vertex_a.x + self.vertex_b.x) / 2.0,
        y: (self.vertex_a.y + self.vertex_b.y) / 2.0,
    };

    let m_bc = Point {
        x: (self.vertex_b.x + self.vertex_c.x) / 2.0,
        y: (self.vertex_b.y + self.vertex_c.y) / 2.0,
    };

    let m_ca = Point {
        x: (self.vertex_c.x + self.vertex_a.x) / 2.0,
        y: (self.vertex_c.y + self.vertex_a.y) / 2.0,
    };

    let m_ab_slope = -(self.vertex_b.x - self.vertex_a.x) / (self.vertex_b.y - self.vertex_a.y);
    let m_bc_slope = -(self.vertex_c.x - self.vertex_b.x) / (self.vertex_c.y - self.vertex_b.y);
    let m_ca_slope = -(self.vertex_a.x - self.vertex_c.x) / (self.vertex_a.y - self.vertex_c.y);

    let x_o = (m_ab.y - m_ab_slope * m_ab.x + m_bc.y - m_bc_slope * m_bc.x + m_ca.y - m_ca_slope * m_ca.x)
        / (m_ab_slope + m_bc_slope + m_ca_slope);

    let y_o = m_ab_slope * (x_o - m_ab.x) + m_ab.y;

    Point { x: x_o, y: y_o }
}

// 计算三角形的角度
pub fn classify_triangle(&self) -> TriangleType {
    let (angle_a, angle_b, angle_c) = self.classify_angles();

    if angle_a < 90.0 && angle_b < 90.0 && angle_c < 90.0 {
        TriangleType::Acute
    } else if angle_a == 90.0 || angle_b == 90.0 || angle_c == 90.0 {
        TriangleType::Right
    } else {
        TriangleType::Obtuse
    }
}
// 计算三角形的角度
pub fn classify_angles(&self) -> (f64, f64, f64) {
    let angle_a = self.angle_between(&self.vertex_b, &self.vertex_c, &self.vertex_a);
    let angle_b = self.angle_between(&self.vertex_a, &self.vertex_c, &self.vertex_b);
    let angle_c = self.angle_between(&self.vertex_a, &self.vertex_b, &self.vertex_c);

    (angle_a, angle_b, angle_c)
}

// 计算两条边之间的角度
fn angle_between(&self, p1: &Point, p2: &Point, p3: &Point) -> f64 {
    let a = p1.distance_to(p2);
    let b = p2.distance_to(p3);
    let c = p3.distance_to(p1);

    let cos_angle = (a.powi(2) + b.powi(2) - c.powi(2)) / (2.0 * a * b);
    let angle_rad = cos_angle.acos();

    // 将弧度转换为角度
    let angle_deg = angle_rad.to_degrees();

    angle_deg
}

// 计算三角形的角度
pub fn classify_triangle(&self) -> TriangleType {
    let (angle_a, angle_b, angle_c) = self.classify_angles();

    if angle_a < 90.0 && angle_b < 90.0 && angle_c < 90.0 {
        TriangleType::Acute
    } else if angle_a == 90.0 || angle_b == 90.0 || angle_c == 90.0 {
        TriangleType::Right
    } else {
        TriangleType::Obtuse
    }
}
// 计算三角形的角度
pub fn classify_angles(&self) -> (f64, f64, f64) {
    let angle_a = self.angle_between(&self.vertex_b, &self.vertex_c, &self.vertex_a);
    let angle_b = self.angle_between(&self.vertex_a, &self.vertex_c, &self.vertex_b);
    let angle_c = self.angle_between(&self.vertex_a, &self.vertex_b, &self.vertex_c);

    (angle_a, angle_b, angle_c)
}

// 计算两条边之间的角度
fn angle_between(&self, p1: &Point, p2: &Point, p3: &Point) -> f64 {
    let a = p1.distance_to(p2);
    let b = p2.distance_to(p3);
    let c = p3.distance_to(p1);

    let cos_angle = (a.powi(2) + b.powi(2) - c.powi(2)) / (2.0 * a * b);
    let angle_rad = cos_angle.acos();

    // 将弧度转换为角度
    let angle_deg = angle_rad.to_degrees();

    angle_deg
}